[Node.js] AWS Lambda関数の同期呼び出しを非同期に行いたい
こんにちは、CX事業本部 Delivery部の若槻です。
今回は、AWS Lambda関数の同期呼び出しを非同期に行う方法を確認してみました。
やりたいこと
具体的にやりたいことは次の通りです。Lambda関数の挙動をコードでテストするのが目的です。
- Lambda関数を同期的に呼び出し
- 1の2秒後に別の処理を実行
- 1の呼び出しのレスポンスペイロードを取得
1と3の間に2を行いため、1と2の処理を非同期で実行する必要があります。
Promise.all()を使えば良さそう
複数の処理を非同期で実行しつつ実行結果を取得したい場合はPromise.all()
を使うと良さそうです。
Promise.all()
は複数のPromiseオブジェクトを配列で指定し、全てのPromiseが解決できたらそれぞれの戻り値を配列で返します。
const promise1 = Promise.resolve(3); const promise2 = 42; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values); }); // Array [3, 42, "foo"]
また「2. 1の2秒後に別の処理を実行」はsetTimeout()
を使うと良さそうです。
setTimeout(code, delay)
やってみた
Lambda関数のハンドラー。(実際のものより簡略化しています)
export const handler = async (): Promise<string> => { await new Promise((r) => setTimeout(r, 5000)); // Sleepを5秒入れて、1と3の間に2を行うようにする return 'aaa'; };
Lambda呼び出しのレスポンスペイロードを取得するスクリプト。
import { InvocationType, InvokeCommand, LambdaClient, } from '@aws-sdk/client-lambda'; const lambdaClient = new LambdaClient({ region: 'ap-northeast-1', }); const main = async (): Promise<void> => { const promiseResults = await Promise.all([ // 1. Lambda関数を同期的に呼び出し lambdaClient.send( new InvokeCommand({ FunctionName: 'nyaoFunc', InvocationType: InvocationType.RequestResponse, }) ), // 2. 1の2秒後に別の処理(省略)を実行 setTimeout((r) => r, 2000), ]); const lambdaResponse = promiseResults[0]; // 3. 1の呼び出しのレスポンスペイロードを取得 console.log(Buffer.from(lambdaResponse.Payload!).toString()); }; main();
スクリプトを実行すると、Lambda関数の実行時間5秒を経てレスポンスペイロードを取得できました。
$ time npx ts-node script.ts "aaa" npx ts-node script.ts 1.59s user 0.15s system 26% cpu 6.568 total
参考
以上